package ThreadDemo.ThreadDemo6;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User:周次煜
 * Date: 2024-07-22
 * Time：21:21
 */


/**
 * 利用三个线程 A, B, C
 * 打印 C, B, A
 *
 * 方案一： 后面等待， 前面相互唤醒法
 */
public class Demo2 {

  private static Object locker1= new Object();
  private static Object locker2= new Object();
    public static void main(String[] args) throws InterruptedException {


        Thread t1 = new Thread(()->{

//            进行等待
//            等待着 线程2 开始唤醒
            synchronized(locker2) {
                try {
                    locker2.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }

            System.out.println("a");
        });

        Thread t2 = new Thread(()-> {

            // 进行等待
            // 等待着 线程3 开始唤醒
            synchronized(locker1) {
                try {
                    locker1.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }

            System.out.println("b");

//             下一步唤醒 线程1

            synchronized (locker2) {
                locker2.notify();
            }

        });



        Thread t3 = new Thread(()->{

//            先等待0.1妙
//            让后面线程 先进行等待
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("c");


//           之后催动后面的线程2开始执行
            synchronized(locker1) {
                locker1.notify();
            }
        });



        t1.start();
        t2.start();
        t3.start();


        t1.join();
        t2.join();
        t3.join();

    }
}


/**
 * 方案二：
 *
 * 每个需要调度的线程都进行等待
 * 最终在主线程中进行管理唤醒执行
 *
 */

class  Demo11 {
    private static  Object locker1 = new Object();

   private static  Object locker2 = new Object();

    private static  Object locker3 = new Object();
    public static void main(String[] args) throws InterruptedException {

        // 在各自线程中进行等待
        Thread t1 =new  Thread(()->{
            synchronized(locker1) {
                try {
                    locker1.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("A");

        });


        Thread t2 =new  Thread(()->{
            synchronized(locker2) {
                try {
                    locker2.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("B");
        });


        Thread t3 =new  Thread(()->{
            synchronized(locker3) {
                try {
                    locker3.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("C");
        });


        t1.start();
        t2.start();
        t3.start();

        // 在主线程中分别唤醒

        Thread.sleep(100);
        synchronized (locker1) {
            locker1.notify();

        }
        Thread.sleep(100);

        synchronized (locker2) {
            locker2.notify();

        }

        Thread.sleep(100);

        synchronized (locker3) {
            locker3.notify();

        }



    }
}


class DemoWait {

    public static Object locker = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(()->{
            synchronized(locker) {
//                进行加锁并等待
                try {
                    locker.wait(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

            }

            System.out.println("hello t");
        });

//        创建线程
        t.start();
//        Thread.sleep(100);
        System.out.println("开始打印t");
        synchronized(locker) {
//            唤醒t
            locker.notify();

        }

//        等待t 结束
            t.join();

        // 打印日志
        System.out.println("t 打印完毕！");
    }
}




